namespace Filters.Demo
{
    using System;
    using System.Collections.Generic;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Windows.Forms;
    using Filters.Demo.Core;
    using Filters.Demo.Core.FilterConfiguration;
    using Filters.Demo.DataAccess;
    using Filters.Demo.MetricSpaces;
    using Filters.Demo.Properties;

    /// <summary>
    /// Summary description for MainForm.
    /// </summary>
    public partial class MainForm : System.Windows.Forms.Form, IHost
    {
        private readonly FiltersForm filtersForm;
        private readonly IImageCatalogRepository repository;
        private readonly IMetricSpacesHelper metricSpacesHelper;

        public MainForm(IImageCatalogRepository repository, IMetricSpacesHelper metricSpacesHelper)
        {
            this.InitializeComponent();

            this.filtersForm = new FiltersForm(this);
            this.repository = repository;
            this.metricSpacesHelper = metricSpacesHelper;
            this.metricSpacesHelper.Repository = repository;
        }

        public IImageFilter CurrentImageFilter
        {
            get { return this.dockManager.ActiveDocument as IImageFilter; }
        }

        public void RegisterMenuItem(MenuItem item)
        {
            this.Menu.MenuItems.Add(item);
        }

        public void UnregisterMenuItem(MenuItem item)
        {
            this.Menu.MenuItems.Remove(item);
        }

        public void SaveCurrentImage(string fileName)
        {
            var format = ImageFormat.Jpeg;
            var imageForm = this.dockManager.ActiveDocument as ImageForm;

            if (imageForm != null)
            {
                // resolve file format
                switch (Path.GetExtension(fileName).ToUpperInvariant())
                {
                    case ".JPEG":
                    case ".JPG":
                        format = ImageFormat.Jpeg;
                        break;
                    case ".BMP":
                        format = ImageFormat.Bmp;
                        break;
                    default:
                        MessageBox.Show(this, "Unsupported image format was specified", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                }

                // save the image
                try
                {
                    imageForm.CurrentImage.Save(this.saveFileDialog.FileName, format);
                }
                catch
                {
                    MessageBox.Show(this, "Failed writing image file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        // On File->Exit menu item
        private void ExitFilrItemClick(object sender, EventArgs e)
        {
            Application.Exit();
        }

        // On File->Open menu item
        private void OpenFileItemClick(object sender, System.EventArgs e)
        {
            if (this.openFileDialog.ShowDialog() == DialogResult.OK)
            {
                ImageForm imageForm = null;

                try
                {
                    // create image document
                    imageForm = new ImageForm(this.openFileDialog.FileName, this, this.repository, this.metricSpacesHelper);
                    imageForm.Text = Path.GetFileName(this.openFileDialog.FileName);
                }
                catch (ApplicationException ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                if (imageForm != null)
                {
                    this.filtersForm.Show(this.dockManager);
                    
                    imageForm.Show(this.dockManager);
                    imageForm.Focus();

                    // set events
                    this.SetupDocumentEvents(imageForm);

                    // update filters
                    this.UpdateFiltersForm(imageForm.Filters);
                }
            }
        }

        private void UpdateFiltersForm(IList<FilterElement> filters)
        {
            this.filtersForm.UpdateFiltersList(filters);
        }

        private void SaveFileItemClick(object sender, EventArgs e)
        {
            var imageForm = this.dockManager.ActiveDocument as ImageForm;

            if (imageForm != null)
            {
                // set initial file name
                if (!string.IsNullOrEmpty(imageForm.FileName))
                {
                    this.saveFileDialog.FileName = Path.GetFileName(imageForm.FileName);
                }
                else
                {
                    this.saveFileDialog.FileName = imageForm.Text + ".jpg";
                }

                this.saveFileDialog.FilterIndex = 0;

                // show dialog
                if (this.saveFileDialog.ShowDialog(this) == DialogResult.OK)
                {
                    this.SaveCurrentImage(this.saveFileDialog.FileName);
                }
            }
        }

        private void ReloadFileItemClick(object sender, EventArgs e)
        {
            var doc = this.dockManager.ActiveDocument as ImageForm;

            if (doc != null)
            {
                try
                {
                    doc.Reload();
                }
                catch (ApplicationException ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        // Setup events
        private void SetupDocumentEvents(ImageForm imageForm)
        {
            imageForm.FilterApplied += this.ImageFormFilterApplied;
        }

        private void ImageFormFilterApplied(object sender, FilterEventArgs e)
        {
            this.filtersForm.UpdateFiltersList(e.Filters);
        }
        
        private void FileItemPopup(object sender, EventArgs e)
        {
            var doc = this.dockManager.ActiveDocument;
            var docOpened = doc != null;

            this.reloadFileItem.Enabled = docOpened && (doc is ImageForm) && (((ImageForm)doc).FileName != null);
            this.saveFileItem.Enabled = docOpened;
        }

        private void DockManagerActiveDocumentChanged(object sender, EventArgs e)
        {
            var imageForm = this.dockManager.ActiveDocument as ImageForm;

            if (imageForm != null)
            {
                this.UpdateFiltersForm(imageForm.Filters);
            }
        }

        private void SelectNewPivotsItemClick(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;

            this.metricSpacesHelper.SelectNewPivots(Settings.Default.DistanceCoefficient);

            this.Cursor = Cursors.Default;
            MessageBox.Show("The pivots were successfully regenerated", "Select New Pivots", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}
